package com.beauty.inventory.service.impl;

import com.beauty.inventory.service.CacheService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class RedissonCacheServiceImpl implements CacheService {

    private final RedissonClient redissonClient;
    private final ObjectMapper objectMapper;
    
    private static final String CACHE_KEY_PREFIX = "inventory:cache:";
    private static final long DEFAULT_TTL = 1;
    private static final TimeUnit DEFAULT_TTL_UNIT = TimeUnit.HOURS;

    @Override
    public <T> void set(String key, T value, long ttl, TimeUnit unit) {
        String cacheKey = CACHE_KEY_PREFIX + key;
        log.info("【Redisson缓存】准备设置缓存，key: {}, TTL: {}秒, Redisson传输模式: {}", 
                key, unit.toSeconds(ttl), redissonClient.getConfig().getTransportMode());
        
        RBucket<String> bucket = redissonClient.getBucket(cacheKey);
        
        try {
            String jsonValue = objectMapper.writeValueAsString(value);
            bucket.set(jsonValue, ttl, unit);
            log.info("【Redisson缓存】设置缓存成功，key: {}, TTL: {}秒, 值长度: {}", 
                    key, unit.toSeconds(ttl), jsonValue.length());
        } catch (JsonProcessingException e) {
            log.error("【Redisson缓存】序列化值失败，key: {}, 异常: {}", key, e.getMessage(), e);
            throw new RuntimeException("序列化缓存值失败", e);
        }
    }

    @Override
    public <T> void set(String key, T value) {
        set(key, value, DEFAULT_TTL, DEFAULT_TTL_UNIT);
    }

    @Override
    public <T> T get(String key, Class<T> clazz) {
        String cacheKey = CACHE_KEY_PREFIX + key;
        log.info("【Redisson缓存】准备获取缓存，key: {}, 返回类型: {}", key, clazz.getSimpleName());
        
        RBucket<String> bucket = redissonClient.getBucket(cacheKey);
        
        String jsonValue = bucket.get();
        if (jsonValue == null) {
            log.info("【Redisson缓存】缓存不存在，key: {}", key);
            return null;
        }
        
        try {
            T value = objectMapper.readValue(jsonValue, clazz);
            log.info("【Redisson缓存】获取缓存成功，key: {}, 值长度: {}, TTL: {}秒", 
                    key, jsonValue.length(), bucket.remainTimeToLive() / 1000);
            return value;
        } catch (JsonProcessingException e) {
            log.error("【Redisson缓存】反序列化值失败，key: {}, 异常: {}", key, e.getMessage(), e);
            throw new RuntimeException("反序列化缓存值失败", e);
        }
    }

    @Override
    public boolean delete(String key) {
        String cacheKey = CACHE_KEY_PREFIX + key;
        log.info("【Redisson缓存】准备删除缓存，key: {}", key);
        
        boolean result = redissonClient.getBucket(cacheKey).delete();
        log.info("【Redisson缓存】删除缓存{}，key: {}", result ? "成功" : "失败（可能不存在）", key);
        return result;
    }

    @Override
    public boolean exists(String key) {
        String cacheKey = CACHE_KEY_PREFIX + key;
        boolean result = redissonClient.getBucket(cacheKey).isExists();
        log.info("【Redisson缓存】检查缓存是否存在，key: {}, 结果: {}", key, result);
        return result;
    }

    @Override
    public boolean expire(String key, long ttl, TimeUnit unit) {
        String cacheKey = CACHE_KEY_PREFIX + key;
        log.info("【Redisson缓存】准备设置缓存过期时间，key: {}, TTL: {}秒", key, unit.toSeconds(ttl));
        
        boolean result = redissonClient.getBucket(cacheKey).expire(ttl, unit);
        log.info("【Redisson缓存】设置缓存过期时间{}，key: {}, TTL: {}秒", 
                result ? "成功" : "失败（可能不存在）", key, unit.toSeconds(ttl));
        return result;
    }
} 